public class DesignPatternsExample {

    // 单例模式 (Singleton Pattern)
    static class Singleton {
        private static Singleton instance;

        private Singleton() {
        }

        public static synchronized Singleton getInstance() {
            if (instance == null) {
                instance = new Singleton();
            }
            return instance;
        }

        public void showMessage() {
            System.out.println("Hello from Singleton");
        }
    }

    // 工厂模式 (Factory Pattern)
    interface Shape {
        void draw();
    }

    static class Circle implements Shape {
        @Override
        public void draw() {
            System.out.println("Circle.draw()");
        }
    }

    static class Rectangle implements Shape {
        @Override
        public void draw() {
            System.out.println("Rectangle.draw()");
        }
    }

    static class ShapeFactory {
        public Shape getShape(String shapeType) {
            switch (shapeType.toLowerCase()) {
                case "circle":
                    return new Circle();
                case "rectangle":
                    return new Rectangle();
                default:
                    return null;
            }
        }
    }

    // 命令模式 (Command Pattern)
    static class Light {
        public void on() {
            System.out.println("Light is ON");
        }

        public void off() {
            System.out.println("Light is OFF");
        }
    }

    interface Command {
        void execute();
    }

    static class LightOnCommand implements Command {
        private final Light light;

        public LightOnCommand(Light light) {
            this.light = light;
        }

        @Override
        public void execute() {
            light.on();
        }
    }

    static class LightOffCommand implements Command {
        private final Light light;

        public LightOffCommand(Light light) {
            this.light = light;
        }

        @Override
        public void execute() {
            light.off();
        }
    }

    static class RemoteControl {
        private Command command;

        public void setCommand(Command command) {
            this.command = command;
        }

        public void pressButton() {
            command.execute();
        }
    }

    // 装饰者模式 (Decorator Pattern)
    interface Coffee {
        String getDescription();

        double getCost();
    }

    static class SimpleCoffee implements Coffee {
        @Override
        public String getDescription() {
            return "Simple Coffee";
        }

        @Override
        public double getCost() {
            return 1.0;
        }
    }

    abstract static class CoffeeDecorator implements Coffee {
        protected Coffee decoratedCoffee;

        public CoffeeDecorator(Coffee c) {
            this.decoratedCoffee = c;
        }

        @Override
        public String getDescription() {
            return decoratedCoffee.getDescription();
        }

        @Override
        public double getCost() {
            return decoratedCoffee.getCost();
        }
    }

    static class MilkDecorator extends CoffeeDecorator {
        public MilkDecorator(Coffee c) {
            super(c);
        }

        @Override
        public String getDescription() {
            return super.getDescription() + ", Milk";
        }

        @Override
        public double getCost() {
            return super.getCost() + 0.5;
        }
    }

    static class SugarDecorator extends CoffeeDecorator {
        public SugarDecorator(Coffee c) {
            super(c);
        }

        @Override
        public String getDescription() {
            return super.getDescription() + ", Sugar";
        }

        @Override
        public double getCost() {
            return super.getCost(); // 糖是免费的
        }
    }

    // 测试所有模式
    public static void main(String[] args) {
        // 单例模式测试
        Singleton singletonInstance = Singleton.getInstance();
        singletonInstance.showMessage();

        // 工厂模式测试
        ShapeFactory shapeFactory = new ShapeFactory();
        Shape circle = shapeFactory.getShape("circle");
        if (circle != null) {
            circle.draw();
        }

        // 命令模式测试
        Light light = new Light();
        RemoteControl remote = new RemoteControl();
        remote.setCommand(new LightOnCommand(light));
        remote.pressButton();
        remote.setCommand(new LightOffCommand(light));
        remote.pressButton();

        // 装饰者模式测试
        Coffee simpleCoffee = new SimpleCoffee();
        Coffee milkCoffee = new MilkDecorator(simpleCoffee);
        Coffee sugarMilkCoffee = new SugarDecorator(milkCoffee);

        System.out.println(sugarMilkCoffee.getDescription() + " - $" + sugarMilkCoffee.getCost());
    }
}